netcat文档翻译:网络猫 – 从此网络连接轻而易举,Netcat – network connections made easy
原文: http://www.stearns.org/doc/nc-intro.current.html
在我创建了那些终端脚本中,有一大部分都会将一个命令的输出通过管道输入到另一个命令,例如:
$ cat /var/log/messages | awk '{print $4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15}' | sed -e 's/\[[0-9]*\]:/:/' | sort | uniq | less
它会显示出做了以下处理之后的系统日志文件:去除时间戳,去除[12345]这样的进程编号,去除重复项(1000条整洁的、排序过的、唯一的日志行,比6000 条混乱的日志行要容易阅读得多)。
如果所有的处理都可以在同一台机器上完成的话,则,以上技术狠好用。假如我想将这些数据通过管道发送到另一台机器上呢?例如,我不想使用这台机器上的less来查看这些日志,而是想将输出内容发送到我的笔记本电脑,再用笔记本电脑来查看它。理想情况下,对应的命令可能会是这样的:
$ cat /var/log/messages | awk '{print $4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15}' | sed -e 's/\[[0-9]*\]:/:/' | sort | uniq | laptop
这样的语法是不起作用的,因为,终端脚本会认为自己应当将数据传递给一个叫做laptop 的 程序 ——这个程序并不存在。然而,还是有办法的。
Netcat是5年前编写的,正是用来实现这种神奇的功能——使得用户无需编程就能够在不同机器之间建立网络连接。让我们来看一些用法示例。
假设,我遇到一个有问题的网页服务器,它并未返回我所想要的内容。我想知道,对于某个特定的请求,它回复的 究竟 是什么:
echo -e "GET http://mason.stearns.org HTTP/1.0\n\n" | nc mason.stearns.org 80 | less
以下是我通过less 看到的结果:
HTTP/1.1 200 OK
Date: Sun, 12 Nov 2000 22:56:42 GMT
Server: Apache/1.3.3 (Unix) (Red Hat/Linux)
Last-Modified: Thu, 26 Oct 2000 05:13:45 GMT
ETag: "15941-577c-39f7bd89"
Accept-Ranges: bytes
Content-Length: 22396
Connection: close
Content-Type: text/html
<html>
<head>
<title>Mason - the automated firewall builder for Linux</title>
<META NAME="keywords" CONTENT="firewall, Linux, packet, filter, ipfwadm, ipchains, automated, rules, iptables, netfilter, builder">
</head>
<body>
<center><img src="mason-banner.gif"></center>
...
echo命令为我创建了一个HTTP请求。HTTP协议要求在请求的末尾带上两个换行符,所以我用了两个\n来创建它们。实际的netcat命令(nc)会从标准输入流(stdin)读取到这个请求。我所使用的命令行参数("mason.stearns.org 80")告诉netcat要连接到服务器上的80 端口,然后发送"GET http..."命令。然后,Netcat监听回复(网页以及所有的协议头)并且将其内容传递给less命令。妳可以从下图中理解netcat的工作方式:
Web Server
^ |
| v
^ |
| v
echo --> netcat --> less
向上指向"Web"的那个箭头,表示向外发出的网页请求,而从server 向下指的那个箭头,表示返回的网页。
现在,我可以查看从服务器返回的具体html内容,这样就可以仔细研究在这个html 请求中发生了什么。
我们已经见识了,netcat可以用作一个tcp/ip客户端程序,使得我们可以连接到一个远程服务器,向它发送一个请求,然后将回复的内容传递给别的程序。它还可以用作一个服务器。
我想要建立一个简单的服务器,用来报告我编写的Mason 软件的稳定版及开发版。我希望它运行于mason.stearns.org 的1500 端口。我还希望无需再编写另一个软件来完成这个工作。尽管我可以将这个信息放置在某个可被finger 访问的文件中,但是,我不倾向于运行finger服务器,因为,那存在着安全性和隐私性方面的隐患。首先,我创建一个文件,其中记录着我想要分享的信息:
<pre>
The latest versions of Mason are:
STABLE: 0.13.0
DEVELOPMENT: 0.13.9.3
</pre>
为什么使用<pre>标记?我希望这砣信息可以同时被netcat客户端和网页浏览器访问到。如果我省掉<pre>标记,则,网页浏览器会将所有内容显示在同一行。好了,现在,我们告知服务器,当有客户端连接上来的时候,就发送这个文件的内容:
while true ; do cat /home/wstearns/mason-version | nc -l -p 1500 | head --bytes 2000 >>/tmp/requests ; date >>/tmp/requests ; done
"while true; do....done"会在一个无限循环中运行这个命令。因为netcat在发送了单个文件之后立即退出,所以,这段脚本又会立即再次启动netcat,于是又可以接受下次请求了。
"cat"将版本信息文件的内容传递给netcat;这就是我想要回复给用户的文本内容。
"nc -l -p 1500"告知netcat要监听( listen)端口( port) 1500 。一旦它在1500 端口上接收了一个连接,就会将mason-version 文本内容发送到远程的客户端。客户端发送的请求内容中,前面最多2000个字节的内容会被追加到/tmp/requests文件中,然后再追加该请求的时间戳。这就提供了一个简单的日志功能,同时可以避免某个坏蛋向那个端口发送几G的数据以至于塞满了/tmp所在的硬盘。
在客户端机器上,我可以连接到这个服务器,以查看Mason 的最新版本信息:
[wstearns@sparrow wstearns]$ nc localhost 1500
<pre>
The latest versions of Mason are:
STABLE: 0.13.0
DEVELOPMENT: 0.13.9.3
</pre>
[wstearns@sparrow wstearns]$
当客户端收到回复内容的时候, /tmp/requests 中就会包含有 "Sun Nov 12 18:33:01 EST 2000" 。 我还可以用浏览器来查看这个数据,只需要打开 http://mason.stearns.org:1500 就行了。 在浏览器中看,除了<pre>标记不见了之外,其它内容都是相同的。 妳还可以使用 "telnet mason.stearns.org 1500" ; 它返回的内容会与"nc localhost 1500"相同。
日志文件中记录了网页浏览器发送的协议头内容:
GET / HTTP/1.0
User-Agent: Mozilla/4.75 [en] (X11; U; Linux 2.4.0-test11 i686)
Pragma: no-cache
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*
Accept-Encoding: gzip
Accept-Language: en
Accept-Charset: iso-8859-1,*,utf-8
Via: 1.0 sparrow.websense.net:3128 (Squid/2.3.STABLE4)
X-Forwarded-For: 127.0.0.1
Host: 127.0.0.1:1500
Cache-Control: max-age=259200
Connection: keep-alive
Sun Nov 12 18:39:47 EST 2000
对于创建一个真正的服务器,只剩下最后一条细节事项了。我希望它在启动阶段就运行起来,并且以非root用户来运行。以下是要向/etc/rc.d/rc.local中添加的代码行:
nohup su nobody -c 'while true ; do cat /home/wstearns/mason-version | nc -l -p 1500 | head --bytes 2000 >>/tmp/requests ; date >>/tmp/requests ; done' &
将/home/wstearns/mason-version替换成妳想要显示的文件,将/tmp/requests替换成妳想要使用的日志文件,于是,妳就拥有了一个立即可用的服务器,可用来显示任意数据。如果妳不想要日志功能,那么,将">>/tmp/requests"替换成">>/dev/null",并且删除"; date >>/tmp/requests"就可以了。
netcat 还有一个非常有趣的用途,在调试网络通信内容时非常有用。还记得我们的第一个示例吗?我们想要看到远程服务器回复的详细内容。那么,如果我们想要看人们向我们的某个服务器发送的所有请求,并且想要看服务器回复给他/她们的内容,怎么做呢?其实这并不难。
让我们来监视mason.stearns.org 上的网页服务器。首先,我们要告诉这个服务器监听另一个端口,例如81。具体做法就是,编辑"/etc/httpd/httpd.conf",将"Listen 80"改成"Listen 127.0.0.1:81",然后重启网页服务器。
现在,我们启动一个netcat服务器,监听80 端口。我们还会启动一个netcat客户端,与工作于81 端口的真正网页服务器通信。让它们将自己接收到的数据互相传递给对方,这样,它们就组成了一个 代理 ;即为某个插入到网络连接中间的东西。以下是我们使用的命令:
mknod backpipe p
nc -l -p 80 0<backpipe | tee -a inflow | nc localhost 81 | tee -a outflow 1>backpipe
因为bash的管道只会向一个方向传递数据,所以,我们还需要提供一种手段来传递回复数据。我们可以使用mknod 命令来在本地文件系统上创建一个管道,以传递反方向的数据;这个命令只需要执行一次。
从客户端向此代理发起的请求,首先来到监听于80 端口的第一个nc命令。它们被传递给"tee"命令,该命令会将它们记录到inflow文件中,然后被传递给第二个nc命令,它会将这些数据传递给真正的网页服务器。当服务器回复了数据的时候,首先到达第二个nc命令,被第二个tee命令记录到outflow文件中,然后被推送到本地文件系统上的backpipe 管道中。由于第一个netcat就在监听那个管道,所以,这些回复内容被传递给第一个netcat,然后它就将这些内容回复给原始的客户端。
nc-tee-nc-tee 命令的具体形式,取决于多种因素:妳是想要手动启动它们,还是想要在一个开机脚本中启动它们;妳想要它们自动重新启动,还是只想监听某个单个连接。妳可以写一个跟前文中的"nohup su nobody -c 'while...done' & 类似的脚本,这样就产生了一个可通过开机脚本启动的持久代理,但是,可能需要做点小调整。
尽管上面这个示例是用来监视网页服务器的tcp数据流的,但是,以上技巧可以用来监视任意的tcp连接。实际上,由于nc也支持udp数据包——这是telnet做不到的——因此,甚至应当能够用类似的手段来创建udp代理。
Your opinionsHxLauncher: Launch Android applications by voice commands